CSRF란?
신뢰할 수 있는 사용자를 사칭해 웹 사이트에 원하지 않는 명령어를 보내는 공격 기
CSRF 해킹 조건
- 보안이 취약한 서버로부터 이미 로그인되어 있는 상태여야 함.
- 쿠키 기반의 서버 세션 정보를 획득할 수 있어야 함.
- 공격자는 서버를 공격하기 위한 요청 방법에 대해 미리 파악하고 있어야함.
CSRF 해킹 동작 원리
- 보안이 취약한 서버에 로그인
- 서버에 저장된 세션 정보를 사용할 수 있는 session ID가 사용자의 브라우저 쿠키에 저장됨
- 사용자가 악성 스크립트 페이지를 누르도록 유도
- 악성 스크립트를 직접 전달 혹은 웹 브라우저에 의해 쿠키에 저장된 session ID와 함께 서버로 요청.
- 서버에 담긴 session ID를 통해 해당 요청이 인증된 사용자로부터 온 것으로 판단, 처리
CSRF 예방 방법
-
의심 되는 URL 조심하기 [사용자 입장]
- 의심되는 URL을 함부로 클릭하지 않고, 의심되는 메일을 열어보지 않는 것.
-
Referer check [개발자, 운영자 입장]
- HTTP 요청 헤더 정보에 있는 Referrer정보와 호스트 정보를 비교해서 일치해야 함.
- JAVA servlet 경우 intercepter클래스를 만들어서 모든 요청에 대해 방버 가능.
public class ReferrerCheck implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String referer = request.getHeader("Referer"); String host = request.getHeader("host"); if (referer == null || !referer.contains(host)) { response.sendRedirect("/"); return false; } return true; } } -
CAPTCHA [개발자, 운영자 입장]
- CAPTCHA를 이용하여, 인증코드가 없거나, 요청을 거부하도록 가능.
-
CSRF 토큰 사용 [개발자, 운영자 입장]
- 세션에 임의에 값을 저장 → 모든 요청에 해당 값을 포함하여 전송.
- 세션에 저장된 값과 요청으로 전송된 값이 일치한지를 바타응로 검증.
session.setAttribute("CSRF_TOKEN", UUID.randomUUID().toString());
// session value에 CSRF_TOKEN값 저장<form action="<http://example/path>" method="POST">
<input type="hidden" name="CSRF_TOKEN" value="${CSRF_TOKEN}">
<!-- ... -->
</form>
//CSRF_TOKEN 값을 전송하도록 해public class CsrfTokenInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession httpSession = request.getSession();
String csrfTokenParam = request.getParameter("CSRF_TOKEN");
String csrfTokenSession = (String) httpSession.getAttribute("CSRF_TOKEN");
if (csrfTokenParam == null || !csrfTokenParam.equals(csrfTokenSession)) {
response.sendRedirect("/");
return false;
}
return true;
}
}
//요청 받을시, 인터셉터에서 CSRF_TOKEN값 검증하도록 함.